package com.interactive1.utils;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;

// Referenced classes of package com.interactive1.utils:
//            Config

public class Log
{

    private Log(String s)
    {
        type = DEBUG + "" + INFO + "" + WARNING + "" + ERROR;
        depth = 0x7fffffff;
        enabled = true;
        printTimestamp = true;
        printName = true;
        printDepth = true;
        printType = true;
        printMessage = true;
        echoStdout = false;
        echoStderr = false;
        error = false;
        exception = null;
        name = s;
    }

    public boolean checkError()
    {
        return error;
    }

    public boolean close()
    {
        PrintStream printstream = getPrintStream(fileName);
        synchronized(printstream)
        {
            if(printstream != System.out && printstream != System.err)
            {
                printstream.close();
                printStreams.remove(printstream);
            }
        }
        return printstream.checkError() ^ true;
    }

    public boolean delete()
    {
        boolean flag = false;
        PrintStream printstream = getPrintStream(fileName);
        synchronized(printstream)
        {
            if(printstream != System.out && printstream != System.err)
            {
                printstream.close();
                printStreams.remove(printstream);
                try
                {
                    File file = new File(fileName);
                    flag = file.delete();
                }
                catch(Exception _ex) { }
            }
        }
        return flag;
    }

    public static synchronized boolean delete(String s)
    {
        if(s == null || "".equals(s))
            s = "DEFAULT";
        Log log = getInstance(s);
        logs.remove(s);
        return log.delete();
    }

    public void disable()
    {
        enabled = false;
    }

    public void enable()
    {
        enabled = true;
    }

    protected void finalize()
        throws Throwable
    {
        close();
        super.finalize();
    }

    public String formatEntry(int i, char c, String s)
    {
        StringBuffer stringbuffer = new StringBuffer();
        SimpleDateFormat simpledateformat = new SimpleDateFormat(timestampFormat);
        if(printTimestamp)
        {
            GregorianCalendar gregoriancalendar = new GregorianCalendar();
            stringbuffer.append(simpledateformat.format(gregoriancalendar.getTime()) + "\t");
        }
        if(printName)
            stringbuffer.append("[" + name + "]\t");
        if(printDepth)
            stringbuffer.append(i + "\t");
        if(printType)
            stringbuffer.append(c + "\t");
        if(printMessage)
            stringbuffer.append(s);
        return stringbuffer.toString();
    }

    private static boolean getBoolean(String s, boolean flag)
    {
        boolean flag1 = flag;
        try
        {
            s = Config.mem.getString(s);
        }
        catch(Exception _ex) { }
        try
        {
            char c = Character.toUpperCase(s.charAt(0));
            if(c == 'Y' || c == 'T')
                flag1 = true;
            else
            if(c == 'N' || c == 'F')
                flag1 = false;
        }
        catch(Exception _ex) { }
        return flag1;
    }

    public static Enumeration getCachedLogNames()
    {
        return logs.keys();
    }

    public int getDepth()
    {
        return depth;
    }

    public Exception getException()
    {
        return exception;
    }

    public String getFileName()
    {
        return fileName;
    }

    public static Log getInstance()
    {
        return getInstance(null);
    }

    public static synchronized Log getInstance(String s)
    {
        if(s == null || "".equals(s))
            s = "DEFAULT";
        Log log = (Log)logs.get(s);
        if(log == null)
        {
            log = new Log(s);
            log.readProperties();
            logs.put(s, log);
        }
        return log;
    }

    public static synchronized PrintStream getPrintStream(String s)
    {
        PrintStream printstream = getPrintStream(s, 0);
        if(printstream == null)
            printstream = System.out;
        return printstream;
    }

    private static PrintStream getPrintStream(String s, int i)
    {
        PrintStream printstream = null;
        printstream = (PrintStream)printStreams.get(s);
        if(printstream == null)
        {
            printstream = openPrintStream(s);
            if(printstream == null)
                return null;
            printStreams.put(s, printstream);
        }
        printstream.flush();
        if(!printstream.checkError())
            return printstream;
        printStreams.remove(s);
        if(i > 0)
            return null;
        else
            return getPrintStream(s, ++i);
    }

    public String getType()
    {
        return type;
    }

    public boolean isEnabled()
    {
        return enabled;
    }

    private static PrintStream openPrintStream(String s)
    {
        PrintStream printstream = null;
        if("stdout".equalsIgnoreCase(s))
            printstream = System.out;
        else
        if("stderr".equalsIgnoreCase(s))
            printstream = System.err;
        else
            try
            {
                printstream = new PrintStream(new FileOutputStream(s, true));
            }
            catch(Exception _ex) { }
        return printstream;
    }

    private boolean println(String s)
    {
        boolean flag = true;
        PrintStream printstream = getPrintStream(fileName);
        synchronized(printstream)
        {
            printstream.println(s);
            if(printstream.checkError())
            {
                PrintStream printstream1 = getPrintStream(fileName);
                printstream1.println(s);
                if(printstream1.checkError())
                {
                    error = true;
                    exception = new IOException("Cannot write to log.");
                    flag = false;
                }
            }
        }
        if(echoStdout)
            synchronized(System.out)
            {
                System.out.println(s);
            }
        if(echoStderr)
            synchronized(System.err)
            {
                System.err.println(s);
            }
        return flag;
    }

    public synchronized void readProperties()
    {
        String s = null;
        s = "Log." + name + ".";
        type = Config.mem.getString(s + "type", DEBUG + "" + INFO + "" + WARNING + "" + ERROR);
        depth = Config.mem.getInt(s + "depth", 0x7fffffff);
        enabled = getBoolean(s + "enabled", true);
        fileName = Config.mem.getString(s + "file", "stdout");
        timestampFormat = Config.mem.getString(s + "timestampFormat", "[yy.MM.dd HH:mm:ss.SSS]");
        printTimestamp = getBoolean(s + "printTimestamp", true);
        printName = getBoolean(s + "printName", true);
        printDepth = getBoolean(s + "printDepth", true);
        printType = getBoolean(s + "printType", true);
        printMessage = getBoolean(s + "printMessage", true);
        echoStdout = getBoolean(s + "echoStdout", false);
        echoStderr = getBoolean(s + "echoStderr", false);
    }

    public boolean write(char c, String s)
    {
        return write(0, c, s);
    }

    public boolean write(int i, char c, String s)
    {
        if(!enabled)
            return false;
        c = Character.toUpperCase(c);
        if(type.indexOf(c) < 0 || i > depth)
        {
            return false;
        } else
        {
            println(formatEntry(i, c, s));
            return true;
        }
    }

    public boolean write(int i, String s)
    {
        return write(i, INFO, s);
    }

    public boolean write(String s)
    {
        return write(0, INFO, s);
    }

    public static char DEBUG = 'D';
    public static char INFO = 'I';
    public static char WARNING = 'W';
    public static char ERROR = 'E';
    private static Hashtable logs = new Hashtable();
    private static Hashtable printStreams = new Hashtable();
    private String fileName;
    private String name;
    private String type;
    private int depth;
    private String timestampFormat;
    private boolean enabled;
    private boolean printTimestamp;
    private boolean printName;
    private boolean printDepth;
    private boolean printType;
    private boolean printMessage;
    private boolean echoStdout;
    private boolean echoStderr;
    private boolean error;
    private Exception exception;
}
